package cc.admin.modules.graduate.service.impl;

import cc.admin.common.api.vo.Result;
import cc.admin.common.sys.query.QueryGenerator;
import cc.admin.common.sys.vo.LoginUser;
import cc.admin.common.util.oConvertUtils;
import cc.admin.modules.graduate.entity.*;
import cc.admin.modules.graduate.entity.DTO.DesignQuestionsListDto;
import cc.admin.modules.graduate.mapper.ChoiceErrorQuestionsMultiMapper;
import cc.admin.modules.graduate.mapper.MultiChoiceQuestionsMapper;
import cc.admin.modules.graduate.mapper.TopicMapper;
import cc.admin.modules.graduate.service.IMultiChoiceQuestionsService;
import cc.admin.poi.excel.ExcelExportUtil;
import cc.admin.poi.excel.ExcelImportUtil;
import cc.admin.poi.excel.annotation.Excel;
import cc.admin.poi.excel.def.NormalExcelConstants;
import cc.admin.poi.excel.entity.ExportParams;
import cc.admin.poi.excel.entity.ImportParams;
import cc.admin.poi.excel.export.ExcelExportServer;
import cc.admin.poi.excel.view.PoiEntityExcelView;
import cc.admin.poi.util.ExcelUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UuidUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.IdWorker.getId;

/**
 * @Description: 多选题
 * @Author: cc-admin
 * @Date: 2025-02-24
 * @Version: V1.0.0
 */
@Service
@Slf4j
public class MultiChoiceQuestionsServiceImpl extends ServiceImpl<MultiChoiceQuestionsMapper, MultiChoiceQuestions> implements IMultiChoiceQuestionsService {

    @Autowired
    private MultiChoiceQuestionsMapper multiChoiceQuestionsMapper;

    @Autowired
    private ChoiceErrorQuestionsMultiMapper choiceErrorQuestionsMultiMapper;

    @Autowired
    private TopicMapper topicMapper;

    @Override
    public void saveMultiChoice(MultiChoiceQuestions multiChoiceQuestions) {
        Gson gson = new Gson();
        List<option> option = multiChoiceQuestions.getOption();
        String optionJson = gson.toJson(option);
        List<String> answer = multiChoiceQuestions.getAnswer();
        String answerJson = gson.toJson(answer);
        multiChoiceQuestions.setOptionJson(optionJson);
        multiChoiceQuestions.setAnswerJson(answerJson);
        ArrayList<String> categoryIds = new ArrayList<>();
        ArrayList<String> categoryIdsText = new ArrayList<>();
        List<Category> categorys = multiChoiceQuestions.getCategorys();
        categorys.forEach(category -> {
            categoryIds.add(category.getValue());
            categoryIdsText.add(category.getLabel());
        });
        multiChoiceQuestions.setCategoryIds(String.join(",", categoryIds));
        multiChoiceQuestions.setCategoryIdsText(String.join(",", categoryIdsText));
        multiChoiceQuestionsMapper.insert(multiChoiceQuestions);
    }

    @Override
    public void updateMultiChoice(MultiChoiceQuestions multiChoiceQuestions) {
        Gson gson = new Gson();
        List<option> option = multiChoiceQuestions.getOption();
        String optionJson = gson.toJson(option);
        List<String> answer = multiChoiceQuestions.getAnswer();
        String answerJson = gson.toJson(answer);
        multiChoiceQuestions.setOptionJson(optionJson);
        multiChoiceQuestions.setAnswerJson(answerJson);
        ArrayList<String> categoryIds = new ArrayList<>();
        ArrayList<String> categoryIdsText = new ArrayList<>();
        List<Category> categorys = multiChoiceQuestions.getCategorys();
        categorys.forEach(category -> {
            categoryIds.add(category.getValue());
            categoryIdsText.add(category.getLabel());
        });
        //修改应用错题的解析
        if (multiChoiceQuestions.getViedoUrl() != null && !multiChoiceQuestions.getViedoUrl().equals("")) {
            LambdaUpdateWrapper<ChoiceErrorQuestionsMulti> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(ChoiceErrorQuestionsMulti::getQuestionId, multiChoiceQuestions.getId());
            updateWrapper.set(ChoiceErrorQuestionsMulti::getViedoUrl, multiChoiceQuestions.getViedoUrl());
            choiceErrorQuestionsMultiMapper.update(null, updateWrapper);
        }
        multiChoiceQuestions.setCategoryIds(String.join(",", categoryIds));
        multiChoiceQuestions.setCategoryIdsText(String.join(",", categoryIdsText));
        multiChoiceQuestionsMapper.updateById(multiChoiceQuestions);
    }

    @Override
    public ModelAndView exportXls(HttpServletRequest request, String choiceQuestionIds, String catalog, Class<MultiChoiceQuestions> multiChoiceQuestionsClass, String title) {
        Gson gson = new Gson();
        LambdaQueryWrapper<Topic> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.isNotNull(Topic::getParentId);
        queryWrapper1.ne(Topic::getParentId,"");
        String[] labelArray = topicMapper.selectList(queryWrapper1).stream()
                .map(Topic::getLabel)
                .toArray(String[]::new);
        // Step.1 组装查询条件
        QueryWrapper<MultiChoiceQuestions> queryWrapper = QueryGenerator.initQueryWrapper(new MultiChoiceQuestions(), request.getParameterMap());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (choiceQuestionIds != null && !choiceQuestionIds.isEmpty()) {
            queryWrapper.in("id", Arrays.asList(choiceQuestionIds.split(",")));
        }else {
            //让他查不着数据
            queryWrapper.eq("id","");
        }
        if (catalog != null && !catalog.isEmpty()) {
            queryWrapper.eq("major_id", catalog);
        }
        // Step.2 获取导出数据
        List<MultiChoiceQuestions> pageList = this.list(queryWrapper);
        List<exportMultiChoiceQuestions> exportList = new ArrayList<>();

        pageList.forEach(multiChoiceQuestions -> {
            exportMultiChoiceQuestions exportMultiChoiceQuestions = new exportMultiChoiceQuestions();
            BeanUtils.copyProperties(multiChoiceQuestions,exportMultiChoiceQuestions);
            java.lang.reflect.Type type = new TypeToken<List<option>>() {}.getType();
            java.lang.reflect.Type stringType = new TypeToken<List<String>>() {}.getType();
            List<option> optionList = gson.fromJson(multiChoiceQuestions.getOptionJson(), type);
            String answer = String.join(",",(List<String>)gson.fromJson(multiChoiceQuestions.getAnswerJson(), stringType));
            exportMultiChoiceQuestions.setOptionA(optionList.get(0).getLabel());
            exportMultiChoiceQuestions.setOptionB(optionList.get(1).getLabel());
            exportMultiChoiceQuestions.setOptionC(optionList.get(2).getLabel());
            exportMultiChoiceQuestions.setOptionD(optionList.get(3).getLabel());
            exportMultiChoiceQuestions.setAnswerJson(answer);
            exportList.add(exportMultiChoiceQuestions);
        });

        // Step.3 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new PoiEntityExcelView() {
            @Override
            protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
                String codedFileName = "临时文件";
                Workbook workbook = null;
                //---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
                String[] exportFields = null;

                Object exportFieldStr = model.get(NormalExcelConstants.EXPORT_FIELDS);
                if (exportFieldStr != null && exportFieldStr != "") {
                    exportFields = exportFieldStr.toString().split(",");
                }
                //---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
                if (model.containsKey(NormalExcelConstants.MAP_LIST)) {
                    List<Map<String, Object>> list = (List<Map<String, Object>>) model.get(NormalExcelConstants.MAP_LIST);
                    if (list.size() == 0) {
                        throw new RuntimeException("MAP_LIST IS NULL");
                    }
                    workbook = ExcelExportUtil.exportExcel((ExportParams) list.get(0).get(NormalExcelConstants.PARAMS), (Class<?>) list.get(0).get(NormalExcelConstants.CLASS), (Collection<?>) list.get(0).get(NormalExcelConstants.DATA_LIST), exportFields);
                    for (int i = 1; i < list.size(); i++) {
                        new ExcelExportServer().createSheet(workbook, (ExportParams) list.get(i).get(NormalExcelConstants.PARAMS), (Class<?>) list.get(i).get(NormalExcelConstants.CLASS), (Collection<?>) list.get(i).get(NormalExcelConstants.DATA_LIST), exportFields);
                    }
                } else {
                    workbook = ExcelExportUtil.exportExcel((ExportParams) model.get(NormalExcelConstants.PARAMS), (Class<?>) model.get(NormalExcelConstants.CLASS), (Collection<?>) model.get(NormalExcelConstants.DATA_LIST), exportFields);
                }
                // 在这里进行自定义操作，例如添加下拉列表
                if (workbook != null && workbook.getNumberOfSheets() > 0) {
                    Sheet targetSheet = workbook.getSheetAt(0);
                    ExcelUtil.addValidationToSheet(workbook, targetSheet, labelArray, 'B', 3, 1000);
                    ExcelUtil.addValidationToSheet(workbook, targetSheet, new Object[]{"计算机", "数学", "政治"}, 'A', 3, 1000);
                }
                if (model.containsKey(NormalExcelConstants.FILE_NAME)) {
                    codedFileName = (String) model.get(NormalExcelConstants.FILE_NAME);
                }
                if (workbook instanceof HSSFWorkbook) {
                    codedFileName += HSSF;
                } else {
                    codedFileName += XSSF;
                }
                if (isIE(request)) {
                    codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8");
                } else {
                    codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1");
                }
                response.setHeader("content-disposition", "attachment;filename=" + codedFileName);
                ServletOutputStream out = response.getOutputStream();
                workbook.write(out);
                out.flush();
            }

        });
        mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.CLASS, exportMultiChoiceQuestions.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title));
        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
        return mv;
    }

    @Override
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<MultiChoiceQuestions> multiChoiceQuestionsClass) {
        Gson gson = new Gson();
        HashMap<String, String> childTopicMap = new HashMap<>();
// 查询数据并封装成 Map
        Map<String, String> resultMap = topicMapper.selectList(null).stream()
                .collect(Collectors.toMap(Topic::getLabel, Topic::getValue, (existing, replacement) -> existing, HashMap::new));
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            try {
                Workbook workbook = null;
                InputStream fileInputStream = file.getInputStream();
                String fileName = file.getOriginalFilename();
                if (fileName.endsWith("xlsx")) {
                    workbook = new XSSFWorkbook(fileInputStream);// Excel 2007
                } else if (fileName.endsWith("xls")) {
                    workbook = new HSSFWorkbook(fileInputStream);// Excel 2003
                }
                Sheet sheet = workbook.getSheetAt(0);
                // 存储主表数据
                Map<String, MultiChoiceQuestions> masterMap = new HashMap<>();
                // 存储子表id数据
                List<String> detailIdList = new ArrayList<>();

                // 读取表头
                Row headerRow = sheet.getRow(0);

                for (int i = 3; i <= sheet.getLastRowNum(); i++) {
                    Row row = sheet.getRow(i);
                    Cell masterSubjectTextCell = row.getCell(0); // 主表 科目名称 在第一列
                    Cell masterMajorTextCell = row.getCell(1); // 主表专业在第三列
                    Cell masterQuestionCell = row.getCell(2); // 主表题目在第二列
                    Cell masterOptionACell = row.getCell(3); // 主表选项a在第二列
                    Cell masterOptionBCell = row.getCell(4); // 主表选项b在第二列
                    Cell masterOptionCCell = row.getCell(5); // 主表选项c在第二列
                    Cell masterOptionDCell = row.getCell(6); // 主表选项d在第二列
                    Cell masterAnswerCell = row.getCell(7); // 主表答案在第二列
                    Cell masterAnalysisCell = row.getCell(8); // 主表解析在第二列



                    String masterSubjectText = masterSubjectTextCell.getStringCellValue();
                    String masterQuestionStem = masterQuestionCell.getStringCellValue();
                    String optionA = masterOptionACell.getStringCellValue();
                    String optionB = masterOptionBCell.getStringCellValue();
                    String optionC = masterOptionCCell.getStringCellValue();
                    String optionD = masterOptionDCell.getStringCellValue();
                    String answer = masterAnswerCell.getStringCellValue();
                    String analysis = masterAnalysisCell.getStringCellValue();
                    List<option> optionList = new ArrayList<>();
                    cc.admin.modules.graduate.entity.option option1 = new option(optionA,"A");
                    cc.admin.modules.graduate.entity.option option2 = new option(optionB,"B");
                    cc.admin.modules.graduate.entity.option option3 = new option(optionC,"C");
                    cc.admin.modules.graduate.entity.option option4 = new option(optionD,"D");
                    optionList.add(option1);
                    optionList.add(option2);
                    optionList.add(option3);
                    optionList.add(option4);
                    String masterMajorText = masterMajorTextCell.getStringCellValue();

                    String id = UuidUtils.getUUID();    //主表id
                    String optionJson = gson.toJson(optionList);
                    List<String> answerList = Arrays.stream(answer.split(",")).collect(Collectors.toList());
                    String answerJson = gson.toJson(answerList);
                    // 处理主表数据
                    if (!masterMap.containsKey(id)) {
                        MultiChoiceQuestions master = new MultiChoiceQuestions();
                        master.setId(id);
                        master.setSubjectText(masterSubjectText);
                        master.setQuestion(masterQuestionStem);
                        master.setMajorText(masterMajorText);
                        String masterMajorId = resultMap.get(masterMajorText);
                        String masterSubjectId = ChoiceQuestionsServiceImpl.topicMap.get(masterSubjectText);
                        master.setSubjectId(masterSubjectId);
                        master.setMajorId(masterMajorId);
                        master.setOptionJson(optionJson);
                        master.setAnswerJson(answerJson);
                        master.setAnalysis(analysis);
                        masterMap.put(id, master);
                    }
                }
                //主表数据入库
                masterMap.forEach((k, v) -> {
                    //主表数据入库
                    multiChoiceQuestionsMapper.insert(v);
                });
                workbook.close();
                fileInputStream.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }

    private boolean isIE(HttpServletRequest request) {
        String userAgent = request.getHeader("USER-AGENT").toLowerCase();
        return userAgent.indexOf("msie") > 0 || userAgent.indexOf("trident") > 0;
    }
}
